#pragma  once

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <sstream>
#include <atlstr.h>
#include <Strsafe.h>
#include <wincodecsdk.h>
#include <io.h>
#include <fcntl.h>
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <fstream>
#include <wrl.h>
#include <ctime>

#define MP(i) typedef Microsoft::WRL::ComPtr<##i> i##Ptr;
MP ( IWICBitmapDecoder )
MP ( IWICBitmapFrameDecode )
MP ( IWICMetadataReader )
MP ( IWICMetadataQueryReader )
MP ( IWICImagingFactory )
MP ( IWICMetadataBlockReader )
MP ( IWICMetadataHandlerInfo )
#undef MP

#define ERR(e) {e, #e}

struct WICError {
    HRESULT code;
    const char * value;
} static const  WIC_ERRORS[] = {
    ERR ( WINCODEC_ERR_ABORTED ),
    ERR ( WINCODEC_ERR_ACCESSDENIED ),
    ERR ( WINCODEC_ERR_ALREADYLOCKED ),
    ERR ( WINCODEC_ERR_BADHEADER ),
    ERR ( WINCODEC_ERR_BADIMAGE ),
    ERR ( WINCODEC_ERR_BADMETADATAHEADER ),
    ERR ( WINCODEC_ERR_BADSTREAMDATA ),
    ERR ( WINCODEC_ERR_CODECNOTHUMBNAIL ),
    ERR ( WINCODEC_ERR_CODECPRESENT ),
    ERR ( WINCODEC_ERR_CODECTOOMANYSCANLINES ),
    ERR ( WINCODEC_ERR_COMPONENTINITIALIZEFAILURE ),
    ERR ( WINCODEC_ERR_COMPONENTNOTFOUND ),
    ERR ( WINCODEC_ERR_DUPLICATEMETADATAPRESENT ),
    ERR ( WINCODEC_ERR_FRAMEMISSING ),
    ERR ( WINCODEC_ERR_GENERIC_ERROR ),
    ERR ( WINCODEC_ERR_IMAGESIZEOUTOFRANGE ),
    ERR ( WINCODEC_ERR_INSUFFICIENTBUFFER ),
    ERR ( WINCODEC_ERR_INTERNALERROR ),
    ERR ( WINCODEC_ERR_INVALIDPARAMETER ),
    ERR ( WINCODEC_ERR_INVALIDQUERYCHARACTER ),
    ERR ( WINCODEC_ERR_INVALIDQUERYREQUEST ),
    ERR ( WINCODEC_ERR_INVALIDREGISTRATION ),
    ERR ( WINCODEC_ERR_NOTIMPLEMENTED ),
    ERR ( WINCODEC_ERR_NOTINITIALIZED ),
    ERR ( WINCODEC_ERR_OUTOFMEMORY ),
    ERR ( WINCODEC_ERR_PALETTEUNAVAILABLE ),
    ERR ( WINCODEC_ERR_PROPERTYNOTFOUND ),
    ERR ( WINCODEC_ERR_PROPERTYNOTSUPPORTED ),
    ERR ( WINCODEC_ERR_PROPERTYSIZE ),
    ERR ( WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE ),
    ERR ( WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT ),
    ERR ( WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS ),
    ERR ( WINCODEC_ERR_STREAMWRITE ),
    ERR ( WINCODEC_ERR_STREAMREAD ),
    ERR ( WINCODEC_ERR_STREAMNOTAVAILABLE ),
    ERR ( WINCODEC_ERR_TOOMUCHMETADATA ),
    ERR ( WINCODEC_ERR_UNKNOWNIMAGEFORMAT ),
    ERR ( WINCODEC_ERR_UNEXPECTEDMETADATATYPE ),
    ERR ( WINCODEC_ERR_UNEXPECTEDSIZE ),
    ERR ( WINCODEC_ERR_UNSUPPORTEDOPERATION ),
    ERR ( WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT ),
    ERR ( WINCODEC_ERR_UNSUPPORTEDVERSION ),
    ERR ( WINCODEC_ERR_VALUEOUTOFRANGE ),
    ERR ( WINCODEC_ERR_WRONGSTATE / INTSAFE_E_ARITHMETIC_OVERFLOW ),
    ERR ( INTSAFE_E_ARITHMETIC_OVERFLOW )
};

#undef ERR


#define READ_WIC_STRING(f, out) do {                                    \
	UINT strLen = 0;                                                    \
	result = f(0, 0, &strLen);                                          \
	if (SUCCEEDED(result) && (strLen > 0)) {                            \
	result = f(strLen, out.GetBufferSetLength(strLen), &strLen);    \
	out.ReleaseBuffer(strLen - 1);                                  \
	} else { out = L""; } } while(0);






